package com.wpr.shop.utils;

import com.wpr.shop.modules.global.validate.ErrorCode;
import com.wpr.shop.modules.global.vo.CommonResp;
import com.wpr.shop.utils.servlet.MyHttpResponseWrapper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.servlet.ServletRequest;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.lang.invoke.MethodHandles;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Pattern;
import java.util.zip.GZIPInputStream;

/**
 * describe:
 *
 * @author zhanglisheng
 * @date 2018/10/25
 */
public class InterceptorUtils {
    private static final Logger LOGGER = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());

    /**
     * 获取请求header
     *
     * @param request
     * @return
     * @author qianchun  @date 2015年8月17日 下午2:00:46
     */
    public static String getHeaderJson(HttpServletRequest request) {
        Map<String, Object> headers = new HashMap<String, Object>();
        String requestId = request.getHeader("requestid");
        String appversion = request.getHeader("appversion");
        String acceptEncoding = request.getHeader("Accept-Encoding");
        String token = request.getHeader("token");

        //是否压缩, 自定义字段
        String apiGzip = request.getHeader("Api-Gzip");
        headers.put("requestid", requestId);
        headers.put("appversion", appversion);
        headers.put("Accept-Encoding", acceptEncoding);
        headers.put("Api-Gzip", apiGzip);
        headers.put("Token", token);
        if (request.getHeader("Request-From") != null) {
            headers.put("Request-From", request.getHeader("Request-From"));
        }
        return JsonUtil.obj2Json(headers);
    }

    /**
     * 获取请求参数json
     *
     * @param request
     * @return
     * @author qianchun  @date 2015年8月17日 下午2:00:59
     */
    public static String getRequestData(HttpServletRequest request) {
        if (isMultipartContent(request)) {
            return JsonUtil.obj2Json(request.getParameterMap());
        }
        return getBodyString(request);
    }

    public static String getRequestGzipStr(HttpServletRequest request) {
        try {

            InputStream inputStream = request.getInputStream();
            return decompress(inputStream);
        } catch (Exception e) {
            LOGGER.error("getRequestGzipStr error:", e);
        }
        return null;
    }

    /**
     * 读取request中的数据
     *
     * @param request
     * @return
     */
    public static String getBodyString(ServletRequest request) {
        StringBuilder sb = new StringBuilder();
        InputStream inputStream = null;
        BufferedReader reader = null;
        try {
            inputStream = request.getInputStream();
            reader = new BufferedReader(new InputStreamReader(inputStream, "UTF-8"));
            String line;
            while ((line = reader.readLine()) != null) {
                sb.append(line);
            }
        } catch (IOException e) {
            LOGGER.error("getBodyString error:", e);
        } finally {
            if (inputStream != null) {
                try {
                    inputStream.close();
                } catch (IOException e) {
                    LOGGER.error("getBodyString inputStream close error:", e);
                }
            }
            if (reader != null) {
                try {
                    reader.close();
                } catch (IOException e) {
                    LOGGER.error("getBodyString reader close error:", e);
                }
            }
        }
        return sb.toString();
    }

    /**
     * 截取response响应内容
     *
     * @param response
     * @return
     * @throws IOException
     */
    public static String getResponseDataJson(HttpServletResponse response) throws IOException {
        String responseJsonStr;
        if (response instanceof MyHttpResponseWrapper) {
            MyHttpResponseWrapper myHttpResponseWrapper = (MyHttpResponseWrapper) response;
            responseJsonStr = myHttpResponseWrapper.getContent();
        } else {
            responseJsonStr = response.toString();
        }
        return responseJsonStr;
    }


    /**
     * 设置异常返回结果
     * @param errorCode
     * @param response
     * @return
     * @throws IOException
     */

    public static String setResponse(ErrorCode errorCode, HttpServletResponse response) throws IOException {
        CommonResp resp = new CommonResp(errorCode.getValue(), errorCode.getComment());
        String responseResultJson = JsonUtil.obj2Json(resp);
        response.setHeader("Content-type", "text/html;charset=UTF-8");
        response.getWriter().write(responseResultJson);
        response.flushBuffer();
        return responseResultJson;
    }

    /**
     * 获取统计所用日志
     *
     * @param request
     * @param headerJson
     * @param requstParamsJson
     * @param upTime
     * @param responseResultJson
     * @param systemId
     * @return
     */
    public static String getStatisticsLog(HttpServletRequest request, String systemId, String headerJson,
                                          String requstParamsJson, String responseResultJson, long upTime) {

        String url = request.getRequestURI().substring(request.getContextPath().length());
        StringBuilder statisticsLog = new StringBuilder("[" + HttpUtil.getIpAddr(request) + "] [] [" + url + "]");
        statisticsLog.append(" [" + systemId + "] REQHeader[" + headerJson + "]" + " REQParam[" + requstParamsJson + "]" + " RES[" + responseResultJson + "]" + " CostTime[" + (System.currentTimeMillis() - upTime) + "] finishLog[OK]");
        return statisticsLog.toString();
    }


    /**
     * 解析压缩流
     *
     * @param inputStream
     * @return
     * @throws IOException
     */
    public static String decompress(InputStream inputStream) throws IOException {

        GZIPInputStream gis = new GZIPInputStream(inputStream);
        ByteArrayOutputStream baos = new ByteArrayOutputStream(1024);
        int count;
        int bufferSize = 1024;
        byte[] buffer = new byte[bufferSize];
        while ((count = gis.read(buffer, 0, bufferSize)) != -1) {
            baos.write(buffer, 0, count);
        }

        gis.close();
        String temp = new String(baos.toByteArray(), "UTF-8");
        baos.close();
        return temp;
    }

    /**
     * 检查是否属于白名单
     *
     * @return
     */
    public static boolean checkIsInWhiteList(HttpServletRequest request, List<String> whiteList) {
        String url = request.getRequestURI();
        url = url.substring(request.getContextPath().length());

        if (url.endsWith("/") == false) {
            url = url + "/";
        }
        for (String tmp : whiteList) {
            if (tmp.endsWith("/") == false) {
                tmp = tmp + "/";
            }

            if (tmp.equals(url)) {
                return true;
            }

            if (tmp.contains("\\d") || tmp.contains("\\w") || tmp.contains("*")) {
                boolean flag = Pattern.compile(tmp).matcher(url).find();
                if (flag == true) {
                    return true;
                }
            }
        }
        return false;
    }


    /**
     * 判断请求是否为上传文件
     *
     * @param request
     * @return
     */
    public static boolean isMultipartContent(HttpServletRequest request) {
        if (!"post".equals(request.getMethod().toLowerCase())) {
            return false;
        } else {
            String contentType = request.getContentType();
            return contentType != null && contentType.toLowerCase().startsWith("multipart/");
        }
    }
    /**
     * 判断请求是否为上传文件
     *
     * @param request
     * @return
     */
    public static boolean isNotifyPay(HttpServletRequest request) {
        if (!"post".equals(request.getMethod().toLowerCase())) {
            return false;
        } else {
            String uri = request.getRequestURI();
            return uri != null && uri.toLowerCase().contains("/api/pad/4g/notifypay");
        }
    }
}
